#ifndef LONGKEY_COMMON_SECURITY_RSA_H__
#define LONGKEY_COMMON_SECURITY_RSA_H__

#include "inttypes.h"

class RSA
{
public:
	typedef const uint32_t PublicKeyInstance[];
	typedef const uint32_t* PublicKey;

	// Public_key as Montgomery precomputed array
	explicit RSA(PublicKey public_key) : pkey_(public_key) {}

	//
	// sig[] signature to verify, big-endian byte array.
	// sig_len length of sig[] in bytes.
	// If verified successfully, output receives the recovered
	// message and the function returns the number of bytes.
	// If not successful, the function returns 0.
	// (empty message is not a useful message)
	int verify(const uint8_t* sig, int sig_len,
		void* output, int output_max) const;

	// Hybrid encrypt message.
	//
	// output_max should be at least encryptedSize(msg_len)
	// Returns 0 on failure, # output bytes on success.
	int encrypt(const uint8_t* msg, int msg_len,
		const void* seed, int seed_len,
		uint8_t* output, int output_max) const;

	int encryptedSize(int len) const {
		return len + 1 + 4 + size();
	}

	// Performs in-place public key exponentiation.
	//
	// Input_len should match size of modulus in bytes.
	// Returns 0 on failure, # of bytes written on success.
	int raw(uint8_t* input, int input_len) const;

	int version() const { return pkey_[0]; }
	int size() const { return pkey_[1] * 4; }

private:
	const PublicKey pkey_;
	static const int kMaxWords = 64;
};

#endif  // LONGKEY_COMMON_SECURITY_RSA_H__